// 通用工具函数

/**
 * 深拷贝对象
 * @param {any} obj 要拷贝的对象
 * @returns {any} 拷贝后的对象
 */
export function deepClone(obj) {
  if (obj === null || typeof obj !== 'object') return obj
  if (obj instanceof Date) return new Date(obj.getTime())
  if (obj instanceof Array) return obj.map(item => deepClone(item))
  if (typeof obj === 'object') {
    const clonedObj = {}
    for (const key in obj) {
      if (obj.hasOwnProperty(key)) {
        clonedObj[key] = deepClone(obj[key])
      }
    }
    return clonedObj
  }
}

/**
 * 防抖函数
 * @param {Function} func 要防抖的函数
 * @param {number} delay 延迟时间
 * @returns {Function} 防抖后的函数
 */
export function debounce(func, delay = 300) {
  let timeoutId
  return function (...args) {
    clearTimeout(timeoutId)
    timeoutId = setTimeout(() => func.apply(this, args), delay)
  }
}

/**
 * 节流函数
 * @param {Function} func 要节流的函数
 * @param {number} delay 延迟时间
 * @returns {Function} 节流后的函数
 */
export function throttle(func, delay = 300) {
  let lastCall = 0
  return function (...args) {
    const now = Date.now()
    if (now - lastCall >= delay) {
      lastCall = now
      func.apply(this, args)
    }
  }
}

/**
 * 生成随机字符串
 * @param {number} length 长度
 * @param {string} chars 字符集
 * @returns {string} 随机字符串
 */
export function generateRandomString(length = 8, chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') {
  let result = ''
  for (let i = 0; i < length; i++) {
    result += chars.charAt(Math.floor(Math.random() * chars.length))
  }
  return result
}

/**
 * 生成UUID
 * @returns {string} UUID字符串
 */
export function generateUUID() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    const r = Math.random() * 16 | 0
    const v = c === 'x' ? r : (r & 0x3 | 0x8)
    return v.toString(16)
  })
}

/**
 * 获取URL参数
 * @param {string} name 参数名
 * @param {string} url URL字符串
 * @returns {string|null} 参数值
 */
export function getUrlParam(name, url = window.location.href) {
  const urlObj = new URL(url)
  return urlObj.searchParams.get(name)
}

/**
 * 设置URL参数
 * @param {string} name 参数名
 * @param {string} value 参数值
 * @param {string} url URL字符串
 * @returns {string} 新的URL
 */
export function setUrlParam(name, value, url = window.location.href) {
  const urlObj = new URL(url)
  urlObj.searchParams.set(name, value)
  return urlObj.toString()
}

/**
 * 删除URL参数
 * @param {string} name 参数名
 * @param {string} url URL字符串
 * @returns {string} 新的URL
 */
export function removeUrlParam(name, url = window.location.href) {
  const urlObj = new URL(url)
  urlObj.searchParams.delete(name)
  return urlObj.toString()
}

/**
 * 检查是否为移动设备
 * @returns {boolean} 是否为移动设备
 */
export function isMobile() {
  return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
}

/**
 * 检查是否为iOS设备
 * @returns {boolean} 是否为iOS设备
 */
export function isIOS() {
  return /iPad|iPhone|iPod/.test(navigator.userAgent)
}

/**
 * 检查是否为Android设备
 * @returns {boolean} 是否为Android设备
 */
export function isAndroid() {
  return /Android/.test(navigator.userAgent)
}

/**
 * 获取浏览器信息
 * @returns {object} 浏览器信息
 */
export function getBrowserInfo() {
  const ua = navigator.userAgent
  const browsers = {
    chrome: /Chrome/.test(ua) && /Google Inc/.test(navigator.vendor),
    firefox: /Firefox/.test(ua),
    safari: /Safari/.test(ua) && /Apple Computer/.test(navigator.vendor),
    edge: /Edg/.test(ua),
    ie: /MSIE|Trident/.test(ua)
  }

  const browser = Object.keys(browsers).find(key => browsers[key]) || 'unknown'

  return {
    name: browser,
    version: getBrowserVersion(ua, browser),
    isMobile: isMobile(),
    isIOS: isIOS(),
    isAndroid: isAndroid()
  }
}

/**
 * 获取浏览器版本
 * @param {string} ua User Agent
 * @param {string} browser 浏览器名称
 * @returns {string} 版本号
 */
function getBrowserVersion(ua, browser) {
  const versionRegex = {
    chrome: /Chrome\/(\d+\.\d+)/,
    firefox: /Firefox\/(\d+\.\d+)/,
    safari: /Version\/(\d+\.\d+)/,
    edge: /Edg\/(\d+\.\d+)/,
    ie: /MSIE (\d+\.\d+)|Trident.*rv:(\d+\.\d+)/
  }

  const match = ua.match(versionRegex[browser])
  return match ? match[1] || match[2] : 'unknown'
}

/**
 * 复制文本到剪贴板
 * @param {string} text 要复制的文本
 * @returns {Promise<boolean>} 是否复制成功
 */
export async function copyToClipboard(text) {
  try {
    if (navigator.clipboard && window.isSecureContext) {
      await navigator.clipboard.writeText(text)
      return true
    } else {
      // 降级方案
      const textArea = document.createElement('textarea')
      textArea.value = text
      textArea.style.position = 'fixed'
      textArea.style.left = '-999999px'
      textArea.style.top = '-999999px'
      document.body.appendChild(textArea)
      textArea.focus()
      textArea.select()
      const result = document.execCommand('copy')
      document.body.removeChild(textArea)
      return result
    }
  } catch (error) {
    console.error('复制失败:', error)
    return false
  }
}

/**
 * 获取设备像素比
 * @returns {number} 设备像素比
 */
export function getDevicePixelRatio() {
  return window.devicePixelRatio || 1
}

/**
 * 检查是否支持WebP格式
 * @returns {Promise<boolean>} 是否支持WebP
 */
export function isWebPSupported() {
  return new Promise((resolve) => {
    const webP = new Image()
    webP.onload = webP.onerror = () => {
      resolve(webP.height === 2)
    }
    webP.src = ''
  })
}

/**
 * 等待指定时间
 * @param {number} ms 等待时间（毫秒）
 * @returns {Promise} Promise对象
 */
export function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms))
}

/**
 * 重试函数
 * @param {Function} fn 要重试的函数
 * @param {number} times 重试次数
 * @param {number} delay 重试间隔
 * @returns {Promise} Promise对象
 */
export async function retry(fn, times = 3, delay = 1000) {
  try {
    return await fn()
  } catch (error) {
    if (times > 0) {
      await sleep(delay)
      return retry(fn, times - 1, delay)
    }
    throw error
  }
}

/**
 * 数组去重
 * @param {Array} arr 数组
 * @param {string} key 去重的键名（对象数组时使用）
 * @returns {Array} 去重后的数组
 */
export function uniqueArray(arr, key) {
  if (!Array.isArray(arr)) return arr

  if (key) {
    const seen = new Set()
    return arr.filter(item => {
      const value = item[key]
      if (seen.has(value)) {
        return false
      }
      seen.add(value)
      return true
    })
  }

  return [...new Set(arr)]
}

/**
 * 数组分组
 * @param {Array} arr 数组
 * @param {Function|string} key 分组键或函数
 * @returns {object} 分组后的对象
 */
export function groupBy(arr, key) {
  if (!Array.isArray(arr)) return {}

  return arr.reduce((groups, item) => {
    const groupKey = typeof key === 'function' ? key(item) : item[key]
    if (!groups[groupKey]) {
      groups[groupKey] = []
    }
    groups[groupKey].push(item)
    return groups
  }, {})
}

/**
 * 数组排序
 * @param {Array} arr 数组
 * @param {string} key 排序键名
 * @param {string} order 排序顺序 'asc' | 'desc'
 * @returns {Array} 排序后的数组
 */
export function sortArray(arr, key, order = 'asc') {
  if (!Array.isArray(arr)) return arr

  return [...arr].sort((a, b) => {
    const aVal = key ? a[key] : a
    const bVal = key ? b[key] : b

    if (aVal < bVal) return order === 'asc' ? -1 : 1
    if (aVal > bVal) return order === 'asc' ? 1 : -1
    return 0
  })
}
